/**
 * 	Revised2011Formatter.java
 *
 *  This file is part of the PDFGen Syllabus Formatter Project.
 *  Copyright (C) 2012  Gian Fontanilla
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.dlsu.pdfgen;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;

import org.dlsu.pdfgen.struct.Revised2011Syllabus;
import org.dlsu.pdfgen.struct.Syllabus;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.VerticalPositionMark;

/**
 * Generates the PDF file from a given <CODE>Syllabus</CODE>.
 * 
 * @author Michelle Ormoc
 * @see Revised2011Syllabus
 * 
 */

public class Revised2011Formatter extends Formatter{

	protected static final Chunk tab3 = new Chunk(new VerticalPositionMark(),
			300, false);
	
	public Revised2011Formatter(Revised2011Syllabus s) throws DocumentException,
			FileNotFoundException {
		super(s);
		createDocument(s);
		// TODO Auto-generated constructor stub
	}
	
	public Revised2011Formatter(Revised2011Syllabus s, String outputFileName)
	throws DocumentException, FileNotFoundException {
		super(s, outputFileName);
		createDocument(s);
		}
	
	private static void addTab(Paragraph p) {
		p.add(tab3);
	}
	
	private static List generateLearningList(ArrayList<String> items) {
		List list = new List(false, false, 10);
		list.setListSymbol("");
		for (int i = 0; i < items.size(); i++)
			list.add(new ListItem("LO " + (i + 1) + ": " + new Chunk(items.get(i), fontTimesNorm), fontTimesNorm));			
		return list;
	}
	
	private static PdfPTable generateFinalOutputTable(ArrayList list) {

		float[] colWidth = { 10f, 10f, 5f };
		PdfPTable tbl = new PdfPTable(colWidth);
		tbl.setWidthPercentage(100.0f);
		tbl.addCell(new Phrase(new Chunk("LEARNING OUTCOME", fontTimesBold)));
		tbl.addCell(new Phrase(new Chunk("REQUIRED OUTPUT", fontTimesBold)));
		tbl.addCell(new Phrase(new Chunk("DUE DATE", fontTimesBold)));

		for (int i = 0; i < list.size(); i++) {

			tbl.addCell(new Phrase("LO " + (i + 1) + ":" + new Chunk(
					Revised2011Syllabus.getLearning(list.get(i)), fontTimesNorm), fontTimesNorm));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getOutput(list.get(i)), fontTimesNorm)));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getDate(list.get(i)), fontTimesNorm)));
		}
		return tbl;
	}
	
	private static PdfPTable generateRubricAssessmentTable(ArrayList list) {
		float[] colWidth = { 9f, 11f, 13f, 11f, 10f, 7f };
		PdfPTable tbl = new PdfPTable(colWidth);
		tbl.setWidthPercentage(100.0f);
		tbl.addCell(new Phrase(new Chunk("CRITERIA", fontTimesNorm)));
		tbl.addCell(new Phrase(new Chunk("EXEMPLARY 4", fontTimesNorm)));
		tbl.addCell(new Phrase(new Chunk("SATISFACTORY 3", fontTimesNorm)));
		tbl.addCell(new Phrase(new Chunk("DEVELOPING 2", fontTimesNorm)));
		tbl.addCell(new Phrase(new Chunk("BEGINNING 1", fontTimesNorm)));
		tbl.addCell(new Phrase(new Chunk("RATING", fontTimesNorm)));

		for (int i = 0; i < list.size(); i++) {
			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getCriteria(list.get(i)), fontTimesNorm)));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getExemplary(list.get(i)), fontTimesNorm)));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getSatisfactory(list.get(i)), fontTimesNorm)));
			
			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getDeveloping(list.get(i)), fontTimesNorm)));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getBeginning(list.get(i)), fontTimesNorm)));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getRating(list.get(i)), fontTimesNorm)));
		}
		tbl.addCell(new Phrase(new Chunk("", fontTimesNorm)));

		tbl.addCell(new Phrase(new Chunk("", fontTimesNorm)));

		tbl.addCell(new Phrase(new Chunk("", fontTimesNorm)));
		
		tbl.addCell(new Phrase(new Chunk("", fontTimesNorm)));

		tbl.addCell(new Phrase(new Chunk("TOTAL:", fontTimesBold)));

		tbl.addCell(new Phrase(new Chunk("", fontTimesNorm)));	
		
		return tbl;
	}
	
	private static PdfPTable generateLearningPlanTable(ArrayList list) {

		float[] colWidth = { 8f, 22f, 5f, 8f };
		PdfPTable tbl = new PdfPTable(colWidth);
		tbl.setWidthPercentage(100.0f);
		tbl.addCell(new Phrase(new Chunk("LEARNING OUTCOME", fontTimesBold)));
		tbl.addCell(new Phrase(new Chunk("TOPIC", fontTimesBold)));
		tbl.addCell(new Phrase(new Chunk("WEEK NO.", fontTimesBold)));
		tbl.addCell(new Phrase(new Chunk("LEARNING ACTIVITIES", fontTimesBold)));

		for (int i = 0; i < list.size(); i++) {

			tbl.addCell(new Phrase("LO " + (i + 1) + ": " + new Chunk(
					Revised2011Syllabus.getLearningName(list.get(i)), fontTimesNorm), fontTimesNorm));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getTopic(list.get(i)), fontTimesNorm)));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getWeek(list.get(i)), fontTimesNorm)));

			tbl.addCell(new Phrase(new Chunk(
					Revised2011Syllabus.getActivities(list.get(i)), fontTimesNorm)));
		}

		return tbl;
	}
	
	private void createDocument(Revised2011Syllabus s) throws FileNotFoundException,
	DocumentException {
	
	Document doc = new Document();
	PdfWriter.getInstance(doc, new FileOutputStream(outputFileName));

	doc.setMargins(75.0f, 75.0f, 75.0f, 75.0f);
	doc.setPageSize(PageSize.LETTER);
	doc.open();
	
	// Main heading
	Paragraph mainHeading = new Paragraph(s.getCourseCode() + " SYLLABUS\n\n",
			fontTimesBold);
	mainHeading.setAlignment(Paragraph.ALIGN_CENTER);
	
	// College
	Paragraph collegeStmt = new Paragraph();
	collegeStmt.add(new Chunk("COLLEGE: ", fontTimesBold));
	collegeStmt.add(new Chunk(s.getCollege(), fontTimesNorm));
	
	// Department
	Paragraph departmentStmt = new Paragraph();
	addTab(collegeStmt);
	departmentStmt.add(new Chunk("DEPARTMENT: ", fontTimesBold));
	departmentStmt.add(new Chunk(s.getDepartment(), fontTimesNorm));
	collegeStmt.add(departmentStmt);
	
	// Course Code
	Paragraph codeStmt = new Paragraph();
	codeStmt.add(new Chunk("COURSE CODE: ", fontTimesBold));
	codeStmt.add(new Chunk(s.getCourseCode(), fontTimesNorm));
	
	// Schedule
	Paragraph scheduleStmt = new Paragraph();
	scheduleStmt.add(new Chunk("CLASS DAYS AND CLASS TIME: ", fontTimesBold));
	scheduleStmt.add(new Chunk(s.getTime(), fontTimesNorm));
	
	//Room
	Paragraph roomStmt = new Paragraph();
	roomStmt.add(new Chunk("ROOM: ", fontTimesBold));
	addTab(scheduleStmt);
	roomStmt.add(new Chunk(s.getRoom(), fontTimesNorm));
	scheduleStmt.add(roomStmt);
	
	// Faculty
	Paragraph facultyStmt = new Paragraph();
	facultyStmt.add(new Chunk("INSTRUCTOR: ", fontTimesBold));
	facultyStmt.add(new Chunk(s.getFaculty(), fontTimesNorm));
	
	// Descriptions
	Paragraph descriptionStmt = new Paragraph();
	descriptionStmt.add(new Chunk("COURSE DESCRIPTION: \n", fontTimesBold));
	descriptionStmt.setAlignment(3);
	descriptionStmt.add(new Chunk(s.getCourseDesc(), fontTimesNorm));
	
	// Learning Outcomes
	Paragraph learningStmt = new Paragraph();
	learningStmt.add(new Chunk("LEARNING OUTCOMES (LO):\n", fontTimesBold));
	learningStmt.add(new Chunk(s.getLearningOutcomeDescription(), fontTimesNorm));
	learningStmt.setAlignment(3);
	learningStmt.add(generateLearningList(s.getLearningOutcome()));

	// Final Course Output
	Paragraph finalStmt = new Paragraph();
	finalStmt.add(new Chunk("FINAL COURSE OUTPUT:\n", fontTimesBold));
	finalStmt.add(new Chunk(s.getFinalCourseOutputDescription(), fontTimesNorm));
	finalStmt.setAlignment(3);
	finalStmt.add(generateFinalOutputTable(s.getFinalCourseOutput()));
	
	// Rubric for Assessment
	Paragraph rubricStmt = new Paragraph();
	rubricStmt.add(new Chunk("RUBRIC FOR ASSESSMENT:\n", fontTimesBold));
	rubricStmt.add(new Chunk(s.getRubricDescription(), fontTimesNorm));
	rubricStmt.setAlignment(3);
	rubricStmt.add(generateRubricAssessmentTable(s.getRubric()));
	
	// Other Requirements and Assessments
	Paragraph requirementsStmt = new Paragraph();
	requirementsStmt.add(new Chunk("OTHER REQUIREMENTS AND ASSESSMENTS:\n", fontTimesBold));
	requirementsStmt.add(new Chunk(s.getOtherRequirementsDescription(), fontTimesNorm));
	requirementsStmt.setAlignment(3);
	if (s.getRequirementListType().equalsIgnoreCase("bulleted"))
		requirementsStmt.add(generateBulletedList(s.getOtherRequirements()));
	else if (s.getRequirementListType().equalsIgnoreCase("numbered"))
		requirementsStmt.add(generateNumberedList(s.getOtherRequirements()));
	else if (s.getRequirementListType().equalsIgnoreCase("roman"))
		requirementsStmt.add(generateRomanList(s.getRequirements()));
	else
		requirementsStmt.add(generatePlainList(s.getOtherRequirements()));
	
	// Grading System
	Paragraph gradingStmt = new Paragraph();
	gradingStmt.add(new Chunk("GRADING SYSTEM:\n", fontTimesBold));
	gradingStmt.add(new Chunk(s.getGradingSystemDescription(), fontTimesNorm));
	gradingStmt.setAlignment(3);
	gradingStmt.add(generateBulletedList(s.getGradingSystem()));
	
	// Learning Plan
	Paragraph planStmt = new Paragraph();
	planStmt.add(new Chunk("LEARNING PLAN:\n", fontTimesBold));
	planStmt.add(new Chunk(s.getLearningPlanDescription(), fontTimesNorm));
	planStmt.setAlignment(3);
	planStmt.add(generateLearningPlanTable(s.getLearningPlan()));
	
	// References
	Paragraph referencesStmt = new Paragraph();
	referencesStmt.add(new Chunk("REFERENCES:\n", fontTimesBold));
	referencesStmt.add(new Chunk(s.getReferenceDescription(), fontTimesNorm));
	if (s.getReferenceListType().equalsIgnoreCase("bulleted"))
		referencesStmt.add(generateBulletedList(s.getReferences()));
	else if (s.getReferenceListType().equalsIgnoreCase("numbered"))
		referencesStmt.add(generateNumberedList(s.getReferences()));
	else if (s.getReferenceListType().equalsIgnoreCase("roman"))
		referencesStmt.add(generateRomanList(s.getReferences()));
	else
		referencesStmt.add(generatePlainList(s.getReferences()));
	
	// Online Resource
	Paragraph onlineStmt = new Paragraph();
	onlineStmt.add(new Chunk("REFERENCES:\n", fontTimesBold));
	onlineStmt.add(new Chunk(s.getOnlineResourcesDescription(), fontTimesNorm));
	if (s.getOnlineResourceListType().equalsIgnoreCase("bulleted"))
		onlineStmt.add(generateBulletedList(s.getOnlineResources()));
	else if (s.getOnlineResourceListType().equalsIgnoreCase("numbered"))
		onlineStmt.add(generateNumberedList(s.getOnlineResources()));
	else if (s.getOnlineResourceListType().equalsIgnoreCase("roman"))
		onlineStmt.add(generateRomanList(s.getOnlineResources()));
	else
		onlineStmt.add(generatePlainList(s.getOnlineResources()));
	
	// Class Policies
	Paragraph policyStmt = new Paragraph();
	policyStmt.add(new Chunk("CLASS POLICIES:\n", fontTimesBold));
	policyStmt.add(new Chunk(s.getClassPolicyDescription(), fontTimesNorm));
	if (s.getClassPolicyListType().equalsIgnoreCase("bulleted"))
		policyStmt.add(generateBulletedList(s.getClassPolicy()));
	else if (s.getOnlineResourceListType().equalsIgnoreCase("numbered"))
		policyStmt.add(generateNumberedList(s.getClassPolicy()));
	else if (s.getOnlineResourceListType().equalsIgnoreCase("roman"))
		policyStmt.add(generateRomanList(s.getClassPolicy()));
	else
		policyStmt.add(generatePlainList(s.getClassPolicy()));
	
	doc.add(mainHeading);
	doc.add(collegeStmt);
	doc.add(codeStmt);
	doc.add(scheduleStmt);
	doc.add(facultyStmt);
	addEmptyLine(doc, 1);
	doc.add(descriptionStmt);
	addEmptyLine(doc, 1);
	doc.add(learningStmt);
	addEmptyLine(doc, 1);
	doc.add(finalStmt);
	addEmptyLine(doc, 1);
	doc.add(rubricStmt);
	addEmptyLine(doc, 1);
	doc.add(requirementsStmt);
	addEmptyLine(doc, 1);
	doc.add(gradingStmt);
	addEmptyLine(doc, 1);
	doc.add(planStmt);
	addEmptyLine(doc, 1);
	doc.add(referencesStmt);
	addEmptyLine(doc, 1);
	doc.add(onlineStmt);
	addEmptyLine(doc, 1);
	doc.add(policyStmt);
	
	// Adding metadata
	doc.addCreationDate();
	doc.addTitle(mainHeading.toString());
	doc.addSubject(codeStmt.toString());
	doc.addAuthor(System.getProperty("user.name"));
	
	doc.close();
	}

}
